#ifndef __SINGAL_SLOT_H__
#define __SINGAL_SLOT_H__

#include <vector>
namespace fishingjoy
{
	namespace base
	{
		//===============delegate==================
		template<typename T>
		struct Delegate{};


		//void param.
		template<>
		struct Delegate<void(void)>
		{
			typedef Delegate<void(void)> SELF_CLASS;
			typedef void (SELF_CLASS::*CALL_BACK_FN)();
			typedef void (*GENERIC_CALL_BACK_FN)();
			SELF_CLASS* m_pThis;
			union{
				CALL_BACK_FN m_pMemberCallback;
				GENERIC_CALL_BACK_FN m_pGenericCallback;
			};
			

			Delegate()
				:m_pThis(NULL)
				,m_pMemberCallback(NULL)
			{

			}
			template<typename X>
			Delegate(X* pThis,void(X::*pCallback)())
			{
				this->m_pThis = (SELF_CLASS*)pThis;
				this->m_pMemberCallback = (CALL_BACK_FN)pCallback;
			}

			Delegate(void (*Callback)())
			{
				m_pThis = NULL;
				m_pGenericCallback = Callback;
			}

		public:
			void operator()()
			{
				if(m_pThis!=NULL&& this->m_pMemberCallback!=NULL)
				{
					(m_pThis->*m_pMemberCallback)();
				}
				else if(m_pThis==NULL){
					if(m_pGenericCallback!=NULL)
						m_pGenericCallback();
				}
			}
		};


		//void param.
		template<typename T1>
		struct Delegate<void(T1)>
		{
			typedef Delegate<void(T1)> SELF_CLASS;
			typedef void (SELF_CLASS::*CALL_BACK_FN)();
			typedef void (*GENERIC_CALL_BACK_FN)();
			SELF_CLASS* m_pThis;
			union{
				CALL_BACK_FN m_pMemberCallback;
				GENERIC_CALL_BACK_FN m_pGenericCallback;
			};


			Delegate()
				:m_pThis(NULL)
				,m_pMemberCallback(NULL)
			{

			}
			template<typename X>
			Delegate(X* pThis,void(X::*pCallback)(T1))
			{
				this->m_pThis = (SELF_CLASS*)pThis;
				this->m_pMemberCallback = (CALL_BACK_FN)pCallback;
			}

			Delegate(void (*Callback)(T1))
			{
				m_pThis = NULL;
				m_pGenericCallback = Callback;
			}

		public:
			void operator()(T1 t1)
			{
				if(m_pThis!=NULL&& this->m_pMemberCallback!=NULL)
				{
					(m_pThis->*m_pMemberCallback)(t1);
				}
				else if(m_pThis==NULL){
					if(m_pGenericCallback!=NULL)
						m_pGenericCallback(t1);
				}
			}
		};


		//void param.
		template<typename T1,typename T2>
		struct Delegate<void(T1,T2)>
		{
			typedef Delegate<void(T1,T2)> SELF_CLASS;
			typedef void (SELF_CLASS::*CALL_BACK_FN)(T1,T2);
			typedef void (*GENERIC_CALL_BACK_FN)(T1,T2);
			SELF_CLASS* m_pThis;
			union{
				CALL_BACK_FN m_pMemberCallback;
				GENERIC_CALL_BACK_FN m_pGenericCallback;
			};


			Delegate()
				:m_pThis(NULL)
				,m_pMemberCallback(NULL)
			{

			}
			template<typename X>
			Delegate(X* pThis,void(X::*pCallback)(T1,T2))
			{
				this->m_pThis = (SELF_CLASS*)pThis;
				this->m_pMemberCallback = (CALL_BACK_FN)pCallback;
			}

			Delegate(void (*Callback)(T1,T2))
			{
				m_pThis = NULL;
				m_pGenericCallback = Callback;
			}

		public:
			void operator()(T1 t1,T2 t2)
			{
				if(m_pThis!=NULL&& this->m_pMemberCallback!=NULL)
				{
					(m_pThis->*m_pMemberCallback)(t1,t2);
				}
				else if(m_pThis==NULL){
					if(m_pGenericCallback!=NULL)
						m_pGenericCallback(t1,t2);
				}
			}
		};

		//void param.
		template<typename T1,typename T2,typename T3>
		struct Delegate<void(T1,T2,T3)>
		{
			typedef Delegate<void(T1,T2,T3)> SELF_CLASS;
			typedef void (SELF_CLASS::*CALL_BACK_FN)(T1,T2,T3);
			typedef void (*GENERIC_CALL_BACK_FN)(T1,T2,T3);
			SELF_CLASS* m_pThis;
			union{
				CALL_BACK_FN m_pMemberCallback;
				GENERIC_CALL_BACK_FN m_pGenericCallback;
			};


			Delegate()
				:m_pThis(NULL)
				,m_pMemberCallback(NULL)
			{

			}
			template<typename X>
			Delegate(X* pThis,void(X::*pCallback)(T1,T2,T3))
			{
				this->m_pThis = (SELF_CLASS*)pThis;
				this->m_pMemberCallback = (CALL_BACK_FN)pCallback;
			}

			Delegate(void (*Callback)(T1,T2,T3))
			{
				m_pThis = NULL;
				m_pGenericCallback = Callback;
			}

		public:
			void operator()(T1 t1,T2 t2,T3 t3)
			{
				if(m_pThis!=NULL&& this->m_pMemberCallback!=NULL)
				{
					(m_pThis->*m_pMemberCallback)(t1,t2,t3);
				}
				else if(m_pThis==NULL){
					if(m_pGenericCallback!=NULL)
						m_pGenericCallback(t1,t2,t3);
				}
			}
		};
		//=================signal===========================
		template<typename T>
		struct Signal{};

		//void
		template<>
		struct Signal<void(void)>
		{
			std::vector<Delegate<void(void)> > m_Slots;

			void operator()()
			{
				size_t t = m_Slots.size();
				for(size_t i = 0; i < t; ++i){
					Delegate<void(void)>& d = m_Slots[i];
					d();
				}
			}

			void operator +=(const Delegate<void(void)>& d)
			{
				m_Slots.push_back(d);
			}
		};

		//void(T1)
		template<typename T1>
		struct Signal<void(T1)>
		{
			std::vector<Delegate<void(T1)> > m_Slots;

			void operator()(T1 t1)
			{
				size_t t = m_Slots.size();
				for(size_t i = 0; i < t; ++i){
					Delegate<void(void)>& d = m_Slots[i];
					d(t1);
				}
			}

			void operator +=(const Delegate<void(T1)>& d)
			{
				m_Slots.push_back(d);
			}
		};

		//
		template<typename T1,typename T2>
		struct Signal<void(T1,T2)>
		{
			std::vector<Delegate<void(T1,T2)> > m_Slots;

			void operator()(T1 t1,T2 t2)
			{
				size_t t = m_Slots.size();
				for(size_t i = 0; i < t; ++i){
					Delegate<void(T1,T2)>& d = m_Slots[i];
					d(t1,t2);
				}
			}

			void operator +=(const Delegate<void(T1,T2)>& d)
			{
				m_Slots.push_back(d);
			}
		};

		template<typename T1,typename T2,typename T3>
		struct Signal<void(T1,T2,T3)>
		{
			std::vector<Delegate<void(T1,T2,T3)> > m_Slots;

			void operator()(T1 t1,T2 t2,T3 t3)
			{
				size_t t = m_Slots.size();
				for(size_t i = 0; i < t; ++i){
					Delegate<void(T1,T2,T3)>& d = m_Slots[i];
					d(t1,t2,t3);
				}
			}

			void operator +=(const Delegate<void(T1,T2,T3)>& d)
			{
				m_Slots.push_back(d);
			}
		};
	}
}
#endif